//
//  NSString+YCTools.m
//  Pods
//
//  Created by Apple on 2022/11/1.
//

#import "NSString+YCTools.h"
#import <CommonCrypto/CommonDigest.h>

@implementation NSString (YCTools)

- (BOOL)isContainEmoji
{
    __block BOOL returnValue = NO;
    
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length])
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                              const unichar hs = [substring characterAtIndex:0];
                              if (0xd800 <= hs && hs <= 0xdbff) {
                                  if (substring.length > 1) {
                                      const unichar ls = [substring characterAtIndex:1];
                                      const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                                      if (0x1d000 <= uc && uc <= 0x1f77f) {
                                          returnValue = YES;
                                      }
                                  }
                              } else if (substring.length > 1) {
                                  const unichar ls = [substring characterAtIndex:1];
                                  if (ls == 0x20e3) {
                                      returnValue = YES;
                                  }
                              } else {
                                  if (0x2100 <= hs && hs <= 0x27ff) {
                                      if (hs != 0x2103) {
                                          returnValue = YES;
                                      }
                                  } else if (0x2B05 <= hs && hs <= 0x2b07) {
                                      returnValue = YES;
                                  } else if (0x2934 <= hs && hs <= 0x2935) {
                                      returnValue = YES;
                                  } else if (0x3297 <= hs && hs <= 0x3299) {
                                      returnValue = YES;
                                  } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                                      returnValue = YES;
                                  }
                              }
                          }];
    
    return returnValue;
}

- (BOOL)isContainChinese
{
    NSUInteger length = [self length];
    for (NSUInteger i = 0; i < length; i++) {
        NSRange range = NSMakeRange(i, 1);
        NSString *subString = [self substringWithRange:range];
        const char *cString = [subString UTF8String];
        if (strlen(cString) == 3) {
            return YES;
        }
    }
    return NO;
}

- (BOOL)isContainBlank
{
    NSRange range = [self rangeOfString:@" "];
    if (range.location != NSNotFound) {
        return YES;
    }
    return NO;
}

- (CGFloat)widthForStringWithFont:(UIFont *)font maxHeight:(CGFloat)height {
    CGRect sizeToFit = [self boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, height) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil];
    
    return sizeToFit.size.width + 0.5;
}

- (CGFloat)heightForStringWithFont:(UIFont *)font maxWidth:(CGFloat)width {
    CGRect sizeToFit = [self boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil];
    
    return sizeToFit.size.height + 0.5;
}

- (CGFloat)heightForStringWithFont:(UIFont *)font lineSpacing:(CGFloat)lineSpacing maxWidth:(CGFloat)width {
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    style.lineSpacing = lineSpacing;
    NSDictionary *dic = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:style};
    CGRect sizeToFit = [self boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil];
    
    return sizeToFit.size.height + 0.5;
}

- (NSURL *)stringToUrl {
    if ([self isEqualToString:@""] || [self isEqual:[NSNull null]]) {
        return [NSURL URLWithString:@""];
    }
    
    return [NSURL  URLWithString:self];
}

- (NSData *)stringToData {
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    return data;
}

- (NSDictionary *)stringToDictionary {
    NSData *jsonData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingMutableContainers
                                                          error:&err];
    if(err) {
        
        return nil;
    }
    return dic;
}

- (NSArray *)stringToArray {
    NSData *jsonData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSError *err;
    NSArray *array = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingMutableContainers
                                                          error:&err];
    if(err) {
        
        return nil;
    }
    return array;
}

- (id)stringToJson {
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    id jsonObject = [NSJSONSerialization JSONObjectWithData:data
                                                    options:NSJSONReadingAllowFragments
                                                      error:nil];
    return jsonObject;
}

- (BOOL)isAllNumbers {
    for(int i = 0 ; i < self.length; i++)
    {
        char a = [self characterAtIndex:i];
        if((a>47)&&(a<58))
        {
            continue;
        }
        return NO;
    }
    return YES;
}

+ (BOOL)isNil:(NSString *)targetStr {
    if (targetStr == nil || [targetStr isKindOfClass:[NSNull class]] || ![targetStr isKindOfClass:[NSString class]]) {
        return true;
    }
    
    targetStr = [targetStr stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    if ([targetStr length] == 0){
        return true;
    }
    
    return false;
}

- (BOOL)isNil {
    return [[self class] isNil:self];
}

- (BOOL)contains:(NSString *)subStr
{
    if([NSString isNil:self] || [NSString isNil:subStr])
    {
        return NO;
    }
    
    NSRange range = [self rangeOfString:subStr];
    return range.length != 0;
}

- (BOOL)contains:(NSString *)subStr igonoreCase:(BOOL)isIgnore {
    NSString* selfCopy = self;
    if (isIgnore) {
        selfCopy = [selfCopy uppercaseString];
        subStr = [subStr uppercaseString];
    }
    
    return [selfCopy contains:subStr];
}

- (NSNumber *)getKRateByBitString:(BOOL)isBit
{
    double rate = 0;
    if([NSString isNil: self])
    {
        return [[NSNumber alloc]initWithDouble:rate];
    }
    
    rate = [self doubleValue];
    rate = (rate)/1024.f;
    
    if(!isBit)
    {
        rate = (rate /8);
    }
    
    return [[NSNumber alloc]initWithDouble:rate];
}

+ (BOOL)isNumberStr:(NSString *)str {
    for(int i = 0 ; i < str.length; i++) {
        char a = [str characterAtIndex:i];
        if((a>47)&&(a<58))
        {
            continue;
        }
        return NO;
    }
    return YES;
}

- (BOOL)isLettersAndNumber {
    for(int i = 0; i < self.length; i++)
    {
        char a = [self characterAtIndex:i];
        if(((a>64)&&(a<91)) || ((a>96)&&(a<123)) || ((a>47)&&(a<58))){
            continue;
        }
        return NO;
    }
    return YES;
}

- (BOOL)isPhoneNumber {
    if (self.length != 11 || ![self isAllNumbers]) {
        return NO;
    }
    return YES;
}

//手机号码中间添加空格
- (NSString *)numberSuitEmpty
{
    NSString *subStr_1 = [self substringWithRange:NSMakeRange(0, 3)];
    NSString *subStr_2 = [self substringWithRange:NSMakeRange(3, 4)];
    NSString *subStr_3 = [self substringWithRange:NSMakeRange(7, self.length-7)];
    
    return [NSString stringWithFormat:@"%@ %@ %@",subStr_1, subStr_2, subStr_3];
}

- (BOOL)checkUserID {
    //长度不为18的都排除掉
    if (self.length!=18) {
        return NO;
    }
    
    //校验格式
    NSString *regex2 = @"^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$";
    NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
    BOOL flag = [identityCardPredicate evaluateWithObject:self];
    
    if (!flag) {
        return flag;    //格式错误
    }else {
        //格式正确在判断是否合法
        
        //将前17位加权因子保存在数组里
        NSArray * idCardWiArray = @[@"7", @"9", @"10", @"5", @"8", @"4", @"2", @"1", @"6", @"3", @"7", @"9", @"10", @"5", @"8", @"4", @"2"];
        
        //这是除以11后，可能产生的11位余数、验证码，也保存成数组
        NSArray * idCardYArray = @[@"1", @"0", @"10", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2"];
        
        //用来保存前17位各自乖以加权因子后的总和
        NSInteger idCardWiSum = 0;
        for(int i = 0;i < 17;i++)
        {
            NSInteger subStrIndex = [[self substringWithRange:NSMakeRange(i, 1)] integerValue];
            NSInteger idCardWiIndex = [[idCardWiArray objectAtIndex:i] integerValue];
            
            idCardWiSum+= subStrIndex * idCardWiIndex;
            
        }
        
        //计算出校验码所在数组的位置
        NSInteger idCardMod=idCardWiSum%11;
        
        //得到最后一位身份证号码
        NSString * idCardLast= [self substringWithRange:NSMakeRange(17, 1)];
        
        //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
        if(idCardMod==2)
        {
            if([idCardLast isEqualToString:@"X"]||[idCardLast isEqualToString:@"x"])
            {
                return YES;
            }else
            {
                return NO;
            }
        }else{
            //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
            if([idCardLast isEqualToString: [idCardYArray objectAtIndex:idCardMod]])
            {
                return YES;
            }
            else
            {
                return NO;
            }
        }
    }
}

- (NSString *)numberSuitScanf {
    
    if (self.length > 10) {//如果是手机号码的话
        NSString *numberString = [self stringByReplacingCharactersInRange:NSMakeRange(3, 4) withString:@"****"];
        return numberString;
    }
    return self;
}

- (NSString *)sha1
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
    
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    
    for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
    {
        [output appendFormat:@"%02x", digest[i]];
    }
    
    return output;
}

- (CGSize)sizeWithFont:(UIFont *)font inSize:(CGSize)size {
    
    NSStringDrawingOptions opts = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
    
    NSDictionary *attributes = @{ NSFontAttributeName : font };
    return [self boundingRectWithSize:size
                              options:opts
                           attributes:attributes
                              context:nil].size;
}

- (CGFloat)widthForFont:(UIFont *)font {
    return [self sizeWithAttributes:@{NSFontAttributeName:font}].width+1;
}

- (BOOL)isRangeOfString:(NSString *)string {
    if([self rangeOfString:string].location !=NSNotFound) {
        return YES;
    }else{
        return NO;
    }
}

/**
 将文字依照固定宽度插入一个字符串
 */
- (NSString *)stringByPaddingToFixedWidth:(NSUInteger)length withString:(NSString *)padString startingAtIndex:(NSUInteger)padIndex{
    if (padIndex > self.length) {
        return self;
    }
    NSMutableArray * tempArray = [NSMutableArray array];
    // 剩余的部分长度
    NSInteger remainder = (self.length - padIndex) % length;
    // 可以分成多少段
    NSInteger subsection = (self.length - padIndex) / length ;
    // 循环遍历
    for (NSUInteger i = 0; i < subsection; i++) {
        //
        NSString * tempString = [self substringWithRange:NSMakeRange(padIndex + length * i, length)];
        [tempArray addObject:tempString];
    }
    NSString * paddingString = [tempArray componentsJoinedByString:padString];
    // 拼接上首部分
    if (padIndex > 0) {
        paddingString = [[self substringToIndex:padIndex] stringByAppendingString:paddingString] ;
    }
    // 加上最后一段文字
    if (remainder > 0) {
        paddingString = [paddingString stringByAppendingString:@" "];
        paddingString = [paddingString stringByAppendingString:[self substringWithRange:NSMakeRange(self.length - remainder, remainder)]];
    }
    return paddingString;
}

/// 大小写英文、数字、九宫格中文、全键盘中文、emoji表情
- (BOOL)stringShouldMatchAlphaNumChinese{
    NSString *regex = @"[a-zA-Z]*|[0-9]*|[\u278b-\u2792]*|[\u4e00-\u9fa5]*";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    if([pred evaluateWithObject:self]){
        return YES;
    }
    return NO;
}

- (NSString *)returnsFourDigitString
{
    NSMutableString *str1 = [self stringByReplacingOccurrencesOfString:@" " withString:@""].mutableCopy;
    NSString *str2 = str1.copy;
    for (int i = 0; i < str2.length / 4; i++) {
        if (str2.length % 4 == 0 && (str2.length / 4) - 1 == i) {
            break;
        }
        [str1 insertString:@" " atIndex:(i * 5) + 4];
    }
    return str1.copy;
}

- (NSString*)formatedNumberWithArrNumber:(NSArray *)blankArr{
    NSString *string = self;
    NSInteger stringLength = string.length;
    // 输入及整体改变
    string = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
    for(NSInteger i =0; i < blankArr.count; i ++) {
        NSInteger blankMark = -1;
        for(NSInteger j =0; j <= i ; j ++) {
            blankMark = blankMark + [blankArr[j] integerValue] +1;
        }
        if(blankMark > stringLength) {
            return string;
        }
        NSString *occString = [string substringFromIndex:blankMark];
        string = [[string substringToIndex:blankMark]stringByAppendingFormat:@" %@", occString];
    }
    return string;
}

- (NSString *)ToDivideByWithTimes:(CGFloat)times{
    return [NSString stringWithFormat:@"%.2f",([self floatValue] / times)];
}

- (NSString *)ToMultiplyByWithTimes:(CGFloat)times{
    return [NSString stringWithFormat:@"%.0f",([self floatValue] * times)];
}

- (NSString *)cleanSpecialCharacters {
    if (self == nil) {
        return @"";
    }
    NSString *strResult = nil;
    NSMutableString *originString = [self mutableCopy];
    NSCharacterSet *cs = [NSCharacterSet characterSetWithCharactersInString:@"~!@#$%^&*()+={}':;',[]\\.<>?~！￥%……*（）+【】‘；：”“’。，、？——"];
    NSRange range;
    do {
        range=[originString rangeOfCharacterFromSet:cs options:NSLiteralSearch];
        if (range.location != NSNotFound) {
            [originString deleteCharactersInRange:range];// 删除range代表的字符集
        }
    } while (range.location != NSNotFound);
    strResult = [[NSString alloc] initWithString:originString];
    return strResult;
}

- (NSString *)numberSuitidCardScanf{
    if (self.length > 17) {
        NSString *numberString = [self stringByReplacingCharactersInRange:NSMakeRange(3, 13) withString:@"*************"];
        return numberString;
    }
    return self;
}

- (NSString *)userNameSuitid
{
    if (self.length == 2) {
        NSString *numberString = [self stringByReplacingCharactersInRange:NSMakeRange(1, 1) withString:@"*"];
        return numberString;
    }
    if (self.length == 3) {
        NSString *numberString = [self stringByReplacingCharactersInRange:NSMakeRange(1, self.length - 2) withString:@"*"];
        return numberString;
    }
    if (self.length >= 4) {
        NSString *numberString = [self stringByReplacingCharactersInRange:NSMakeRange(1, self.length - 2) withString:@"**"];
        return numberString;
    }
    return self;
}

- (BOOL)passwordValidate {
    BOOL result = false;
    if ([self length] >= 8 && [self length] <= 16){
        // 判断长度大于8位后再接着判断是否同时包含数字和字符
        NSString * regex = @"^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$";
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
        result = [pred evaluateWithObject:self];
    }
    return result;
}

- (BOOL)matchCityCode:(NSString *)cityCode {
    NSString *tempString = [self substringWithRange:NSMakeRange(0, 4)];
    return [cityCode containsString:tempString];
}

@end
